;;; balance 是全局变量

(define balance 100)

(define (withdraw amount)
	(if (>= balance amount)
		(begin (set! balance (- balance amount)) balance)
		"Insufficient funds"))


;;; 把balance 封装在对象内部，成为一个局部变量

(define new-withdraw 
	(let ((balance 100))
		(lambda (amount)
			(if (>= balance amount)
				(begin (set! balance (- balance amount)) balance)
				"Insufficient funds"))))

;;; 同上，balance 参数，也是局部变量

(define (make-withdraw balance)
	(lambda (amount)
		(if (>= balance amount)
			(begin (set! balance (-balance amount)) balance)
			"Insufficient funds")))

(define W1 (make-withdraw 100))
(define W2 (make-withdraw 100))

(W1 50)
50

(W2 70)
30

(W2 40)
"Insufficient funds"

(W1 40)
10

;;; 存款和取款功能的对象

(define (make-account balance)
	(define (withdraw amount)   ;;; withdraw
		(if (>= balance amount)
			(begin (set! balance (- balance amount)) balance)
			"Insufficient funds"))	

	(define (deposit amount)    ;;; deposit
		(set! balance (+ balance amount))
		balance)

	(define (dispatch m)
		(cond ((eq? m 'withdraw) withdraw)
			  ((eq? m 'deposit)  deposit)
			  (else (error "Unknown request -- MAKE-ACCOUNT"
							m))))
dispatch)

(define acc (make-account 100))

((acc 'withdraw) 50)
50

((acc 'withdraw) 60)
"Insufficient funds"

((acc 'deposit) 40)
90

((acc 'withdraw) 60)
30

练习3.1
(define (make-accumulator x)
	(lambda (n) 
		(begin (set! x (+ n x)) x)))

练习3.2
(define (square x) (* x x)) ;;; 用square 代替 sqrt

(define (make-monitored p)
		(let ((count 0))
			(lambda (input)
				(cond ((eq? input 'how-many-calls?) count)
				      ((eq? input 'reset-count) (begin (set! count 0) count))
				 	  (else (begin (set! count (+ count 1)) (p input)))))))  

练习3.3
(define (make-account balance password)
	(define (withdraw amount)
		(if (>= balance amount)
			(begin (set! balance (- balance amount)) balance)
			"Insufficient funds"))

	(define (deposit amount)
		(set! balance (+ balance amount)))

	(define (password-match? given-password)
		(eq? given-password password))

	(define (display-wrong-password-message useless-arg)
		(display "Incorrect password"))

	(define (dispatch given-password m)
		(if	(password-match? given-password)
			(cond ((eq? m 'withdraw) withdraw)
					((eq? m 'deposit) deposit)
					(else (error "Unknown request --MAKE-ACCOUNT" m)))
			display-wrong-password-message))
dispatch)



;;;;;;;;;;;;;;;;;;;

(define rand
	(let ((x random-init))
		(lambda () (set! x (rand-update x)) x)))

(define (estimate-pi trials)
	(sqrt (/ 6 (monte-carlo trials cesaro-test))))

(define (cesaro-test)
	(= (gcd (rand) (rand)) 1))

(define (monte-carlo trails experiment)
	(define (iter trials-remaining trials-passed)
		(cond ((= trials-remaining 0) (/ trials-passed trials))
			((experiment) (iter (- trials-remaining 1) (+ trials-passed 1)))
			(else (iter (- trials-remaining 1) trials-passed))))
	(iter trials 0))


;;;
(define (make-simplified-withdraw balance)
	(lambda (amount)
		(set! balance (- balance amount)) 
		balance))

(define W (make-simplified-withdraw 25))

(W 20)
5

(W 10)
-5

(define (make-decrementer balance)
	(lambda (amount) (- balance amount)))

(define D (make-decrementer 25))

(D 20)
5

(D 10)
15

;;;
((make-decrementer 25) 20)

((lambda (amount) (- 25 amount)) 20)

(- 25 20)

;;;
((make-simplified-withdraw 25) 20)

((lambda (amount) (set! balance (- 25 amount)) 25) 20)

(set! balance (- 25 20)) 25




























































